<template>
  <div class="screen-recorder">
    <!-- 录制中 -->
    <div class="recording-indicator" v-if="isRecording">
      <div @mousedown="handleMouseDown" class="recording-indicator-timer">
        <div class="recording-dot"></div>
        <div class="recording-text">{{ formatTime(recordingTime) }}</div>
      </div>
      <div @click="stopRecording" class="stop-recording-btn">
        <!-- 停止录制 -->
        <img :src="stopCircleIcon" width="24" draggable="false" :title="$t('screenRecorder.stop')"/>
      </div>
      <div @click="togglePauseRecording" class="pause-recording-btn">
        <!-- 继续录制 -->
        <img v-if="isPaused":src="videoPlayIcon" width="24" draggable="false" :title="$t('screenRecorder.continue')"/>
        <!-- 暂停录制 -->
        <img v-else :src="videoPauseIcon" width="24" draggable="false" :title="$t('screenRecorder.pause')"/>
      </div>
    </div>

    <!-- 选择屏幕录制 -->
    <div v-if="!isRecording" class="screen-recorder-container">
      <div class="header" @mousedown="handleMouseDown">
        <!-- 屏幕录制 -->
        <h1>{{ $t('screenRecorder.title') }}</h1>
        <!-- 关闭 -->
        <el-icon class="header-close-icon" @click="onDestroy" :title="$t('screenRecorder.close')"><Close /></el-icon>
      </div>

      <div class="main-content">
        <div class="source-selector">
          <!-- 选择屏幕 -->
          <h2 @click="onSetLanguage('cn')">{{ $t('screenRecorder.selectScreen') }}</h2>
          <el-scrollbar max-height="430px">
            <div class="source-list">
              <div
                v-for="source in sources"
                :key="source.id"
                class="source-item"
                :class="{ selected: selectedSource?.id === source.id }"
                @click="selectSource(source)"
              >
                <!-- 预览图 -->
                <img :src="source.thumbnail" :alt="$t('screenRecorder.previewImg')" />
                <div class="source-name">{{ source.name }}</div>
              </div>
            </div>
          </el-scrollbar>
        </div>

        <div class="preview-area">
          <!-- 预览 -->
          <h2 @click="onSetLanguage('en')">{{ $t('screenRecorder.preview') }}</h2>
          <div class="video-container">
            <video
              ref="previewVideo"
              autoplay
              muted
              playsinline
              class="preview-video"
            ></video>

            <div v-if="!selectedSource" class="placeholder">
              <div class="placeholder-content">
                <i class="el-icon-monitor"></i>
                <!-- 请选择一个屏幕源进行预览 -->
                <p>{{ $t('screenRecorder.selectPreview') }}</p>
              </div>
            </div>
          </div>

          <div class="controls">
            <!-- 开始录制 -->
            <button
              class="control-btn start-btn"
              :disabled="!selectedSource || isRecording"
              @click="startRecording"
            >
              {{ $t('screenRecorder.start') }}
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, h } from 'vue';
import { ElNotification, ElMessage } from 'element-plus';
import ipcMainApi from '@/ipcMainApi'
import useWindowDrag from '@/hooks/useMouseDown'
import { useI18n } from 'vue-i18n'
const { t } = useI18n({ useScope: 'global' })
import { ElButton } from 'element-plus'
// import { FolderOpened, DocumentCopy, Connection } from '@element-plus/icons-vue'

let { handleMouseDown } = useWindowDrag('screen-recorder-window')

const onSetLanguage = (_val) => {
  // ipcMainApi.publicApi.onSetLanguage(_val)
}

// 图标路径（根据你实际资源路径调整）
const stopCircleIcon = ref(new URL('@/assets/image/screenRecorder/stop-circle.png', import.meta.url).href)
const videoPauseIcon = ref(new URL('@/assets/image/screenRecorder/video-pause.png', import.meta.url).href)
const videoPlayIcon = ref(new URL('@/assets/image/screenRecorder/video-play.png', import.meta.url).href)

const onDestroy = () => {
  ipcMainApi.screenRecorderApi.destroyScreenRecorder()
}

// 屏幕源类型
interface ScreenSource {
  id: string;
  name: string;
  thumbnail: string;
}

const sources = ref<ScreenSource[]>([]);
const selectedSource = ref<ScreenSource | null>(null);
const previewStream = ref<MediaStream | null>(null);
const mediaRecorder = ref<MediaRecorder | null>(null);
const isRecording = ref(false);
const isPaused = ref(false);
const recordingTime = ref(0);
const timer = ref<NodeJS.Timeout | null>(null);
const previewVideo = ref<HTMLVideoElement | null>(null);
const fileName = ref<string | null>(null);

// 获取屏幕源
const getScreenSources = async () => {
  try {
    const screenSources = await ipcMainApi.publicApi.getScreenSources('screen')
    sources.value = screenSources.map(source => ({
      id: source.id,
      name: source.name,
      thumbnail: source.thumbnail.toDataURL()
    }));
    selectSource(screenSources[0])
  } catch (err) {
    console.error('获取屏幕源失败:', err);
    ElNotification.error({
      title: t('screenRecorder.error'), // 错误
      message: t('screenRecorder.screenSourceError'), // 无法获取屏幕源，请检查权限设置
    });
  }
};

// 释放旧流
const stopStream = (stream?: MediaStream | null) => {
  if (!stream) return;
  stream.getTracks().forEach(track => track.stop());
};

// 选择屏幕源
const selectSource = async (source: ScreenSource) => {
  // 释放旧流
  stopStream(previewStream.value);

  selectedSource.value = source;
  try {
    // 获取媒体流
    const stream = await navigator.mediaDevices.getUserMedia({
      audio: false,
      video: {
        mandatory: {
          chromeMediaSource: 'desktop',
          chromeMediaSourceId: source.id,
          minWidth: 1280,
          maxWidth: 1920,
          minHeight: 720,
          maxHeight: 1080
        }
      } as any
    });

    previewStream.value = stream;
    if (previewVideo.value) {
      previewVideo.value.srcObject = stream;
    }
  } catch (err) {
    console.error('获取媒体流失败:', err);
    ElNotification.error({
      title: t('screenRecorder.error'), // 错误
      message: t('screenRecorder.mediaStreamError'), // 无法获取媒体流，请确保选择了有效的屏幕源'
    });
  }
};

// 获取缩略图
const getThumbnail = async (source): Promise<any> => {
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: false,
    video: {
      mandatory: {
        chromeMediaSource: 'desktop',
        chromeMediaSourceId: source.id,
        minWidth: 1280,
        maxWidth: 1920,
        minHeight: 720,
        maxHeight: 1080
      }
    } as any
  });
  const videoNode = document.createElement('video') as HTMLVideoElement
  videoNode.srcObject = stream
  return new Promise((resolve, reject) => {
    videoNode.onloadedmetadata = () => {
      videoNode.play()
      // 生成缩略图
      const canvas = document.createElement('canvas')
      canvas.width = videoNode.videoWidth
      canvas.height = videoNode.videoHeight
      canvas?.getContext('2d')?.drawImage(videoNode, 0, 0)
      stream.getTracks().forEach((track) => track.stop())
      videoNode.srcObject = null;
      videoNode.remove();
      resolve(canvas.toDataURL('image/png'))
    }
    videoNode.onerror = (err) => {
      stream.getTracks().forEach(track => track.stop());
      videoNode.srcObject = null;
      videoNode.remove();
      reject(err)
    }
  })
}

// 等待时间
const wait = (ms) => {
  return new Promise(resolve => setTimeout(resolve, ms))
}

// 开始录制
const startRecording = async () => {
  if (!previewStream.value) return;

  ElNotification.closeAll() // 关闭所有通知
  ElMessage.closeAll() // 关闭所有消息

  await wait(350) // 等待

  mediaRecorder.value = new MediaRecorder(previewStream.value, {
    mimeType: 'video/webm;codecs=vp9'
  });

  mediaRecorder.value.ondataavailable = async(event) => {
    if (event.data.size > 0) {
      // 分段发送视频数据
      const arrayBuffer = await event.data.arrayBuffer();
      const uint8Array = new Uint8Array(arrayBuffer);
      ipcMainApi.screenRecorderApi.sendVideoData(uint8Array)
    }
  };

  mediaRecorder.value.onstop = async () => {
    // 保存文件
    const filePath = await ipcMainApi.screenRecorderApi.saveVideo();

    if (filePath) fileName.value = filePath.split('/').pop() || '';

    // 重置状态
    isRecording.value = false;
    isPaused.value = false;
    recordingTime.value = 0;

    const screenSize = await ipcMainApi.publicApi.getScreenSourcesSize()
    const data = {
      x: screenSize.width / 2 - 400,
      y: screenSize.height / 2 - 300,
      width: 800,
      height: 600,
      isRecording: isRecording.value,
    }
    ipcMainApi.screenRecorderApi.setBoundsScreenRecorder(data)

    selectSource(sources.value[0])
  };

  await ipcMainApi.screenRecorderApi.startRecording() // 通知主进程启动 ffmpeg
  mediaRecorder.value.start(1000); // 每秒收集一次数据
  isRecording.value = true;
  const screenSize = await ipcMainApi.publicApi.getScreenSourcesSize()
  const data = {
    x: screenSize.width / 2 - 75,
    y: 0,
    width: 150,
    height: 40,
    isRecording: isRecording.value,
  }
  ipcMainApi.screenRecorderApi.setBoundsScreenRecorder(data)

  // 开始计时
  timer.value = setInterval(() => {
    recordingTime.value++;
  }, 1000);
};

// 暂停/继续录制
const togglePauseRecording = () => {
  if (!mediaRecorder.value) return;

  if (isPaused.value) {
    mediaRecorder.value.resume();
    timer.value = setInterval(() => {
      recordingTime.value++;
    }, 1000);
  } else {
    mediaRecorder.value.pause();
    if (timer.value) {
      clearInterval(timer.value);
      timer.value = null;
    }
  }

  isPaused.value = !isPaused.value;
};

// 停止录制
const stopRecording = () => {
  if (!mediaRecorder.value) return;

  mediaRecorder.value.stop();

  if (timer.value) {
    clearInterval(timer.value);
    timer.value = null;
  }
};

// 格式化时间
const formatTime = (seconds: number) => {
  const mins = Math.floor(seconds / 60);
  const secs = seconds % 60;
  return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
};

// 清理资源
onUnmounted(() => {
  if (timer.value) {
    clearInterval(timer.value);
  }

  if (previewStream.value) {
    previewStream.value.getTracks().forEach(track => track.stop());
  }
});

// 复制到剪切板
const copyFile = () => {
  if (fileName.value) {
    ipcMainApi.publicApi.copyFileToClipboard(fileName.value).then(() => {
      ElNotification.closeAll() // 关闭所有通知
      ElMessage({
        message: t('screenRecorder.copySuccess'), // 复制文件地址成功
        type: 'success',
      })
    })
  }
}

// 打开文件夹
const openFolder = () => {
  if (fileName.value) {
    ipcMainApi.publicApi.openFolder(fileName.value).then(() => {
      ElNotification.closeAll() // 关闭所有通知
    })
  }
}

// 复制文件路径 
const copyPath = () => {
  if (fileName.value) {
    navigator.clipboard.writeText(fileName.value).then(() => {
      ElNotification.closeAll() // 关闭所有通知
      ElMessage({
        message: t('screenRecorder.copySuccess'), // 复制文件地址成功
        type: 'success',
      })
    }).catch(err => {
      console.error('复制失败:', err)
    })
  }
}

const openFile = () => {
  if (fileName.value) {
    ipcMainApi.publicApi.openFile(fileName.value).then(() => {
      ElNotification.closeAll() // 关闭所有通知
    })
  }
}

onMounted(async () => {
  await getScreenSources();
  for (const item of sources.value) {
    try {
      item.thumbnail = await getThumbnail(item)
    } catch {
      // 出错就用原来的 thumbnail
    }
  }

  // 所有通知
  window.electron.ipcRenderer.on('video-save-callback', (_event, data, filePath) => {
    if (filePath) fileName.value = filePath.split('/').pop() || '';
    if (data === 'ok') {
      ElNotification.success({
        title: t('screenRecorder.recordComplete'), // 录制完成
        message: h('div', { style: 'display: flex; flex-direction: column; gap: 2px;' }, [
          h('div',
            {
              style: { cursor: 'pointer'},
              onClick: () => copyPath(),
            },
            t('screenRecorder.recordCompleteTip') + fileName.value,
          ),
          h('div', { style: 'display: flex; justify-content:flex-end; gap: 2px;' }, [
            h(
              ElButton,
              {
                round: true,
                size: 'small',
                title: t('screenRecorder.copyClipboard'), // 分享
                onClick: copyFile
              },
              () => t('screenRecorder.copyClipboard')
            ),
            h(
              ElButton,
              {
                round: true,
                size: 'small',
                title: t('screenRecorder.open'), // 打开
                onClick: openFile
              },
              () => t('screenRecorder.open')
            ),
            h(
              ElButton,
              {
                round: true,
                size: 'small',
                title: t('screenRecorder.openSaveDirectory'), // 打开保存目录
                onClick: openFolder
              },
              () => t('screenRecorder.openSaveDirectory')
            ),
          ])
        ]),
      });
      // ElNotification.success({
      //   title: t('screenRecorder.recordComplete'), // 录制完成
      //   message: t('screenRecorder.recordCompleteTip') + fileName.value, // 文件已保存为: ${fileName.value}
      // });
    } else if (data === 'cancel') {
      ElNotification.error({
        title: t('screenRecorder.recordCancel'), // 录制取消
        message: t('screenRecorder.recordCancelTip') // 视频录制取消，请重新录制！
      });
    } else {
      ElNotification.error({
        title: t('screenRecorder.recordFailure'), // 录制失败
        message: t('screenRecorder.recordFailureTip'), // 视频录制失败，请重新录制！
      });
    }
  })
});


</script>

<style scoped>
.screen-recorder {
  width: 100vw;
  height: 100vh;
  user-select: none; /* 不允许鼠标复制 */
  position: relative;
  border-radius: 4px;
  overflow: hidden;
}
.screen-recorder-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  /* background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c); */
  background: linear-gradient(135deg, #1a2a6c, #5f34d6, #1a2a6c);
  /* background: #1a2a6c; */
  color: white;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  padding: 20px;
  box-sizing: border-box;
}

.header {
  text-align: center;
  margin-bottom: 20px;
  cursor: pointer;
  position: relative;
}

.header h1 {
  font-size: 1.8rem;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
.header-close-icon {
  position: absolute;
  top: 0;
  right: 0;
  font-size: 1.5rem;
}

.main-content {
  display: flex;
  flex: 1;
  gap: 20px;
}

.source-selector {
  flex: 1;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 10px;
  padding: 15px;
  overflow: hidden;
}

.source-selector h2 {
  margin-top: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  padding-bottom: 10px;
}

.source-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 15px;
  padding: 8px;
  padding-top: 15px;
}

.source-item {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.3s ease;
}

.source-item:hover {
  transform: translateY(-3px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}

.source-item.selected {
  outline: 3px solid #409EFF;
  transform: translateY(-5px);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4);
}

.source-item img {
  width: 100%;
  height: 120px;
  object-fit: cover;
  display: block;
}

.source-name {
  padding: 8px;
  font-size: 0.9rem;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.preview-area {
  flex: 2;
  display: flex;
  flex-direction: column;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 10px;
  padding: 15px;
}

.preview-area h2 {
  margin-top: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  padding-bottom: 10px;
  margin-bottom: 5px;
}

.video-container {
  position: relative;
  flex: 1;
  background: #000;
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 20px;
}

.preview-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}

.placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: rgba(0, 0, 0, 0.5);
}

.placeholder-content {
  text-align: center;
}

.placeholder-content i {
  font-size: 4rem;
  opacity: 0.5;
  margin-bottom: 20px;
}

.placeholder-content p {
  font-size: 1.2rem;
  opacity: 0.7;
}

.recording-indicator {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  background: #000;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 1rem;
}
.recording-indicator-timer {
  display: flex;
  align-items: center;
  cursor: pointer;
}

.recording-dot {
  width: 10px;
  height: 10px;
  background: rgba(255, 0, 0);
  border-radius: 50%;
  animation: pulse 1.5s infinite;
}

@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.5; }
  100% { opacity: 1; }
}


.recording-text {
  margin-left: 10px;
  color:rgba(255, 0, 0);
}
.stop-recording-btn {
  margin-right: 10px;
  margin-left: 10px;
}
.stop-recording-btn,
.pause-recording-btn {
  width: 24px;
  height: 24px;
  cursor: pointer;
}

.controls {
  display: flex;
  justify-content: center;
  gap: 15px;
  flex-wrap: wrap;
}

.control-btn {
  padding: 12px 25px;
  border: none;
  border-radius: 6px;
  font-size: 1rem;
  font-weight: bold;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
}

.control-btn i {
  font-size: 1.2rem;
}

.start-btn {
  background: linear-gradient(to right, #00b09b, #96c93d);
  color: white;
}

.start-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.pause-btn {
  background: linear-gradient(to right, #ff9966, #ff5e62);
  color: white;
}

.pause-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.stop-btn {
  background: linear-gradient(to right, #ff416c, #ff4b2b);
  color: white;
}

.stop-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.download-btn {
  background: linear-gradient(to right, #2193b0, #6dd5ed);
  color: white;
  text-decoration: none;
  text-align: center;
}
</style>
